﻿using System;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using XNOgre.Graphics;
using System.Collections.Generic;

namespace XNOgre.Core
{
    public class Light : MovableObject
    {
        public enum LightType
        {
            Point = 0,
            Directional = 1,
            Spotlight = 2
        }
        private Vector3 position, direction;

        internal Light()
            : base()
        { }
        internal Light(string name)
            : base(name)
        { }

        /// <summary>
        /// Gets/Sets the light type
        /// </summary>
        public LightType Type
        {
            get;
            set;
        }
        /// <summary>
        /// Gets/Sets whether this light should extrude shadows for the renderables it affects.
        /// </summary>
        public new bool CastsShadows
        {
            get;
            set;
        }
        /// <summary>
        /// Gets/Sets the color of the diffuse light given off by this light source
        /// 
        /// <remarks>
        /// Material objects have ambient, diffuse and specular values which indicate how much of each type of light an object reflects.
        /// This value denotes the amount of color of this type of light the light exudes into the scene.
        /// The actual appearance of objects is a combination of the two.
        /// </remarks>
        /// </summary>
        public Color Diffuse
        {
            get;
            set;
        }
        /// <summary>
        /// Gets/Specular light given off by this source.
        /// <remarks>
        /// Material objects have ambient, diffuse and specular values which indicate how much of each type of light an object reflects.
        /// This value denotes the amount of color of this type of light the light exudes into the scene.
        /// The actual appearance of objects is a combination of the two.
        /// 
        /// Specular light affects the appearance of shiny highlights on objects, and is also dependent on the 'shininess' Material value
        /// </remarks>
        /// </summary>
        public Color Specular
        {
            get;
            set;
        }

        /// <summary>
        /// Gets/Set the Position of the light, or the position of the parent node, if any.
        /// Doesn't apply to directional lights
        /// </summary>
        public Vector3 Position
        {
            get
            {
                if (parentNode == null)
                {
                    return position;
                }
                else
                {
                    return parentNode.DerivedPosition;
                }
            }
            set
            {
                if (parentNode == null)
                {
                    position = value;
                }
                else
                {
                    parentNode.Position = value;
                }
            }
        }
        /// <summary>
        /// Gets/Sets the direction of the ligtht.
        /// Doesn't apply to Point lighting
        /// The Direction is always independent of the parent node's, if any.
        /// </summary>
        public Vector3 Direction
        {
            get;
            set;
        }
        /// <summary>
        /// Sets how a light diminishes with distance.
        /// Does not apply to Directional Lights
        /// </summary>
        /// <param name="range">Absolute upper range of the lgith in world units</param>
        /// <param name="constant">The contstant factor in the attenuation formula: 1.0 means never attenuate, 0.0 is complete attenuation</param>
        /// <param name="linear">The linear factor in the attenuation formula: 1 means attenuate evenly over the distance</param>
        /// <param name="quadratic">The quadratic factor in the attenuation formula: adds a curvature to the attenuation formula</param>
        public void SetAttenuation(float range, float constant, float linear, float quadratic)
        {
            AttenuationRange = range;
            AttenuationConstant = constant;
            AttenuationLinear = linear;
            AttenuationQuadric = quadratic;
        }
        
        /// <summary>
        /// The absolute upper range of the light in world units
        /// </summary>
        public float AttenuationRange
        {
            get;
            set;
        }
        /// <summary>
        /// The linear factor in the attenuation formula: 1 means attenuate evenly over the distance
        /// </summary>
        public float AttenuationLinear
        {
            get;
            set;
        }
        /// <summary>
        /// The constant factor in the attenuation formula: 1.0 means never attenuate, 0.0 is complete attenuation
        /// </summary>
        public float AttenuationConstant
        {
            get;
            set;
        }
        /// <summary>
        /// The quadratic factor in the attenuation formula: adds a curvature to the formula
        /// </summary>
        public float AttenuationQuadric
        {
            get;
            set;
        }

        /// <summary>
        /// Angle covered by the inner cone, in Radians
        /// Only applies to Spotlights
        /// </summary>
        public float SpotlightAngle
        {
            get;
            set;
        }
        internal override void UpdateRenderQueue(ref List<IRenderable> queue)
        {
            //
        }
    }
}
